<!DOCTYPE html>
<html>
<head>
	<title>Character Visualisation</title>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
	<script src="lib/zoomcharts.js"></script>
</head>

<body>
	<h1>Characters</h1>
	<div id="demo" style="width: 100%; height: 90%;"></div>

	<script>

// Edit this array to contain zoomcharts style objects for each link and node type
	var styles = {
		'http://contextus.net/ontology/ontomedia/core/expression#has-subject-entity' : { 'toDecoration': 'arrow', 'fillColor': 'black', 'label': 'has-subject-entity' },
		'http://contextus.net/ontology/ontomedia/core/expression#has-object-entity' : { 'toDecoration': 'arrow', 'fillColor': 'black', 'label': 'has-object-entity' },
		'http://contextus.net/ontology/ontomedia/core/expression#to' : { 'toDecoration': 'arrow', 'fillColor': 'yellow', 'label': 'to' },
		'http://contextus.net/ontology/ontomedia/core/expression#from' : { 'toDecoration': 'arrow', 'fillColor': 'yellow', 'label': 'from' },
		'http://contextus.net/ontology/ontomedia/ext/events/social#has-subject' : { 'toDecoration': 'arrow', 'fillColor': 'red', 'label': 'has-subject' },
		'http://contextus.net/ontology/ontomedia/core/expression#Character' : { 'image': 'icons_character.png', 'fillColor': 'yellow', 'radius' : 10 },
		'http://contextus.net/ontology/ontomedia/core/expression#Space' : { 'image': 'icons_space.png', 'fillColor': 'yellow', 'radius' : 10 },
	};

// Edit this array to contain a zoomcharts style object for anything else (currently this is mainly for events)
	var default_style = { 'fillColor': 'green', 'radius' : 20 };

// Edit this array to contain the query string, with __GRAPH__ and __LINK_TYPE__ as placeholders
	var query_string = 'PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \
		PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \
		SELECT  DISTINCT * WHERE { GRAPH ?g { \
		?ref rdf:type <http://contextus.net/ontology/ontomedia/core/expression#Character> \
		OPTIONAL {?ref rdfs:label ?ref_label }. \
		OPTIONAL {?ref <http://www.w3.org/2002/07/owl#sameAs> ?local. \
		?local <http://contextus.net/ontology/ontomedia/core/expression#shadow-of> ?global}. \
		OPTIONAL {?ref <http://contextus.net/ontology/ontomedia/ext/common/trait#has-trait> [rdf:type <http://contextus.net/ontology/ontomedia/ext/common/trait#Name>; \
		<http://contextus.net/ontology/ontomedia/ext/common/trait#has-name> ?ref_name]}. \
		OPTIONAL {?ref <http://contextus.net/ontology/ontomedia/ext/common/trait#has-trait> [rdf:type <http://contextus.net/ontology/ontomedia/ext/common/trait#link>; \
		<http://contextus.net/ontology/ontomedia/ext/common/being#has-bond> [rdf:type ?bond_type; ?bond_rel ?bonded]]}. \
		}}';

// Edit this to point to your public SPARQL endpoint
sparql_root = 'http://brat.kludge.co.uk/sparql/';

// Don't edit anything past here
	var data;
	var chart = null;

	$( document ).ready(function() {
		if (chart == null)
		{
			chart = new NetChart({
	        	container: document.getElementById("demo"),
	        	height: 600,
	        });
 		}

		update_graph();
	});

	String.prototype.hashCode = function(){
	    var hash = 0;
	    if (this.length == 0) return hash;
	    for (var i = 0; i < this.length; i++) {
        	var character = this.charCodeAt(i);
        	hash = ((hash<<5)-hash)+character;
        	hash = hash & hash; // Convert to 32bit integer
    	}
    	return hash;
	}

	function componentToHex ( c ) {
    	var hex = c.toString(16);
    	return hex.length == 1 ? "0" + hex : hex;
	}

	function rgbToHex ( r, g, b ) {
	    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
	}

	function reverse ( s )
	{
	    return s.split("").reverse().join("");
	}

	function update_graph ( )
	{
	    data = { "nodes": [], "links":[] };

		$.ajax({
    		url: sparql_root,
    		dataType: 'json',
		    data: {
        		query: query_string,
		    },

		    success: function( response ) {

		    	// Find all the individual nodes first
		    	$.each(response.results.bindings, function (index, query_data) {
		    		var ref_id = query_data.ref.value;
		    		var ref_label = ref_id;
		    		if ('value' in query_data.ref_label) ref_label = query_data.ref_label.value;
		    		if ('value' in query_data.ref_name) ref_label = query_data.ref_name.value;

		    		var foundR = 0;
		    		for (i = 0; i < data['nodes'].length; i++)
		    		{
		    			if (data['nodes'][i]['id'] == ref_id) foundR = 1;
		    		}

					var hash = reverse(query_data.g.value).hashCode();
					var red = (hash & 0xFF0000) >> 16;
					var green = (hash & 0x00FF00) >> 8;
					var blue = hash & 0x0000FF;

					var ref_style = $.extend({'label': query_data.g.value + "#" + ref_label}, default_style);
					ref_style['fillColor'] = rgbToHex(red,green,blue);
		    		if (foundR == 0) data['nodes'].push({'id': ref_id, style: ref_style});
		    	});

		    	$.each(response.results.bindings, function (index, query_data) {
		    		var ref_id = query_data.ref.value;

					if ('value' in query_data.bonded)
					{
		    			data['links'].push({"id": "link_" + ref_id + '_' + query_data.bonded.value + '_' + query_data.bond_type.value, "from": ref_id, "to": query_data.bonded.value, style: {"label": query_data.bonded.value.split("#")[1] } });
		    		}

					if ('value' in query_data.local)
					{
		    			data['links'].push({"id": "link_" + ref_id + '_' + query_data.local.value + '_' + query_data.bond_type.value, "from": ref_id, "to": query_data.local.value, style: {"label": "Same As" }});
		    		}

					if ('value' in query_data.global)
					{
		    			data['links'].push({"id": "link_" + ref_id + '_' + query_data.global.value + '_' + query_data.bond_type.value, "from": ref_id, "to": query_data.global.value, style: {"label": "Shadow Of" } });
		    		}

		    	});

				chart = new NetChart({
		        	container: document.getElementById("demo"),
	    	    	height: 600,
	        	});
	    		chart.replaceData(data);
    		}
		});

    }




</script>
</body>
</html>